/**
 * \file NotificationManager.h
 * \brief NotificationManager definition class.
 * \author Edouard ROGE
 * \date 10 august 2012
 */

#ifndef _NOTIFICATIONMANAGER_
#define _NOTIFICATIONMANAGER_

#include <vector>
#include "Core/Pattern/ActiveObject.h"
#include "Core/Pattern/Singleton.h"
#include "Notification.h"

namespace Core
{
	namespace Notification
	{
		class NotificationHandler;

		/**
		 * \class NotificationManager
		 * \brief Centralize all the notification, and warn the listener of notification that they are regitered to
		 */
		class NotificationManager : public Singleton<NotificationManager>
		{
		public:

			/**
			 * \fn NotificationManager();
			 * \brief Default constructor
			 */
			NotificationManager();

			/**
			 * \fn ~NotificationManager();
			 * \brief Destructor
			 */
			virtual ~NotificationManager();

			/**
			 * \fn void Register(NotificationHandler * _pHandler, const Notification::NotificationType & _type);
			 * \param _pHandler handler to register
			 * \param _type notification type
			 * \brief Register a handler for a specific type of notification
			 */
			void Register(NotificationHandler * _pHandler, const NotificationType & _type);

			/**
			 * \fn void Unregister(NotificationHandler * _pHandler, const Notification::NotificationType & _type);
			 * \param _pHandler handler to unregister
			 * \param _type notification type
			 * \brief Unregister a handler for a specific type of notification
			 */
			void Unregister(NotificationHandler * _pHandler, const NotificationType & _type);

			/**
			 * \fn void Notify(const Notification & _notification);
			 * \param _notification notification to send to handlers
			 * \brief notify all the handlers which are registered for this kind of notification
			 */
			void Notify(const Notification & _notification);
			
		private:

			/**
			 * \fn void NotifyHandlers(Notification _notification);
			 * \param _notification notification to send to handlers
			 * \brief notify all the handlers which are registered for this kind of notification through the active object
			 */
			void NotifyHandlers(Notification _notification);

			/** Array of handlers for this kind of notification */
			typedef std::vector<NotificationHandler*> Handlers;

			/** type notification handlers */
			Handlers m_pHandlers[Count];

			/** Mutex */
			std::mutex m_mutex;

			/** Active Object */
			ActiveObjectUPtr m_pActiveObject;
		};
	}
}

#endif // _NOTIFICATIONMANAGER_
